﻿using System;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.Shell;

namespace Expect.VisualStudio.Extensions.Commands
{
    public abstract class EditorCommand : OleMenuCommand, ICommand
    {
        private SelectionResolution _resolution;

        protected IExpectPackage _pkg;

        public EditorCommand(IExpectPackage pkg)
            : base(null, new CommandID(Guid.Empty, 0))
        {
            _pkg = pkg;
        }

        public EditorCommand(IExpectPackage pkg, int id)
            : base(Callback, new CommandID(Guids.guidExpect_ExtensionsCmdSet, id))
        {
            _pkg = pkg;
            this.BeforeQueryStatus += new EventHandler(CmdBeforeQueryStatus);
        }

        public abstract string DisplayText { get; }

        public static void Callback(object sender, EventArgs args)
        {
            var cmd = (sender as EditorCommand);
            cmd.ExecuteCommand(cmd._resolution);
        }

        public abstract bool ShowCommand(SelectionResolution resolution);

        public abstract void ExecuteCommand(SelectionResolution resolution);

        void CmdBeforeQueryStatus(object sender, EventArgs e)
        {
            IExpectVSService expectService = (IExpectVSService)GetVSService(typeof(SExpectVSService));
            Visible = false;

            _resolution = expectService.GetCurrentSelectionResolution();
            if (_resolution == null)
            {
                return;
            }

            if (ShowCommand(_resolution))
            {
                (sender as OleMenuCommand).Visible = true;
            }
            else
            {
                (sender as OleMenuCommand).Visible = false;
            }
        }

        protected object GetVSService(Type t)
        {
            return _pkg.GetVSService(t);
        }

        protected bool Ask(string msg)
        {
            return CommandSet.Ask(_pkg, msg);
        }

        protected void ShowMessage(string msg)
        {
            CommandSet.ShowMessage(_pkg, msg);
        }
    }
}
